/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.repository.typetransprocesser;

import com.inspur.edp.cef.api.repository.GspDbDataType;
import com.inspur.edp.cef.api.repository.ITypeTransProcesser;
import com.inspur.edp.cef.entity.entity.FieldType;
import com.inspur.edp.cef.repository.exception.CefRepositoryException;
import com.inspur.edp.cef.spi.entity.info.propertyinfo.*;

public final class TypeTransProcessorFactory {
  public  static ITypeTransProcesser getTypeTransProcessor(DataTypePropertyInfo dataTypePropertyInfo) {
    if (dataTypePropertyInfo.getObjectInfo() != null && (
            dataTypePropertyInfo.getObjectInfo() instanceof EnumPropertyInfo || dataTypePropertyInfo
                    .getObjectInfo() instanceof SimpleEnumUdtPropertyInfo)) {
      EnumPropertyInfo enumPropertyInfo=null;
      if(dataTypePropertyInfo.getObjectInfo() instanceof EnumPropertyInfo)
        enumPropertyInfo= (EnumPropertyInfo) dataTypePropertyInfo.getObjectInfo();
      else
      {
        enumPropertyInfo=((SimpleEnumUdtPropertyInfo)dataTypePropertyInfo.getObjectInfo()).getEnumInfo();
      }
      if(enumPropertyInfo.getRepoType()==null) {
        switch (dataTypePropertyInfo.getDbDataType()) {
          case Int:
            return Enum2IntProcesser.getInstacne(getEnumPropertyInfoClass(dataTypePropertyInfo),enumPropertyInfo);
          case VarChar:
          case NVarChar:
            return Enum2VarcharProcesser.getInstance(enumPropertyInfo);
        }
      }
      else
      {
        switch (enumPropertyInfo.getRepoType()) {
          case  Index:
            return Enum2IntProcesser.getInstacne(getEnumPropertyInfoClass(dataTypePropertyInfo),enumPropertyInfo);
          case Code:
//            if(dataTypePropertyInfo.getObjectInfo() instanceof EnumPropertyInfo)
            return Enum2IntProcesser.getInstacne(getEnumPropertyInfoClass(dataTypePropertyInfo),enumPropertyInfo);
//            else
//              return Enum2VarcharProcesser.getInstacne();
          case StringIndex:
            return Enum2VarcharProcesser.getInstance(enumPropertyInfo);
        }
      }
      throw new CefRepositoryException(
              "#GSPBefError#" + "不支持数据库字段类型为【" + dataTypePropertyInfo.getDbDataType().toString()
                      + "】的枚举字段使用" + "#GSPBefError#");
    }
    if(dataTypePropertyInfo.getObjectInfo() instanceof  SimpleUdtPropertyInfo) {
      return getTransPropcessorByFieldType(dataTypePropertyInfo.getPropertyName(),
              ((SimpleUdtPropertyInfo) dataTypePropertyInfo.getObjectInfo()).getFieldType(),
              dataTypePropertyInfo.getDbDataType());
    }
    if(dataTypePropertyInfo.getObjectInfo() instanceof ComplexUdtPropertyInfo)
    {
      return getTransPropcessorByFieldType(dataTypePropertyInfo.getPropertyName(), FieldType.Text,GspDbDataType.Clob);
    }
    if(dataTypePropertyInfo.getObjectInfo() instanceof EnumPropertyInfo)
    {
      if(((EnumPropertyInfo)dataTypePropertyInfo.getObjectInfo()).getRepoType()==null) {
        switch (dataTypePropertyInfo.getDbDataType()) {
          case Int:
            return Enum2IntProcesser.getInstacne(getEnumPropertyInfoClass(dataTypePropertyInfo),((EnumPropertyInfo)dataTypePropertyInfo.getObjectInfo()));
          case VarChar:
          case NVarChar:
            return Enum2VarcharProcesser.getInstance((EnumPropertyInfo) dataTypePropertyInfo.getObjectInfo());
        }
      }
      else {
        switch (dataTypePropertyInfo.getDbDataType()) {
          case Int:
            return Enum2IntProcesser.getInstacne(((EnumPropertyInfo) dataTypePropertyInfo.getObjectInfo()).getEnumType(),((EnumPropertyInfo)dataTypePropertyInfo.getObjectInfo()));
          case VarChar:
          case NVarChar:
            return Enum2VarcharProcesser.getInstance((EnumPropertyInfo) dataTypePropertyInfo.getObjectInfo());
          default:
            throw new CefRepositoryException(
                    "#GSPBefError#" + "不支持数据库字段类型为【" + dataTypePropertyInfo.getDbDataType().toString() + "】的枚举字段使用" + "#GSPBefError#");
        }
      }
    }
    ITypeTransProcesser typeTransProcesser = getTransPropcessorByFieldType(dataTypePropertyInfo.getPropertyName(), dataTypePropertyInfo.getFieldType(),dataTypePropertyInfo.getDbDataType());
    return typeTransProcesser;
  }

  private static ITypeTransProcesser getTransPropcessorByFieldType(String propertyName, FieldType fieldType,GspDbDataType dbDataType) {
    switch (fieldType) {

      case String:
        return VarcharTransProcesser.getInstacne();
      case Text:
        return ClobTransProcesser.getInstacne();
      case Integer:
        if (dbDataType == GspDbDataType.Int) {
          return IntTransProcesser.getInstacne();
        }
      case Decimal:
        if (dbDataType == GspDbDataType.Decimal) {
          return DecimalTransProcesser.getInstacne();
        }
      case Boolean:
        if (dbDataType == GspDbDataType.Int) {
          return Bool2IntProcesser.getInstacne();
        }
        if (dbDataType == GspDbDataType.Char) {
          return Bool2CharProcesser.getInstacne();
        }
        if (dbDataType == GspDbDataType.Boolean) {
          return BoolTransProcesser.getInstacne();
        }
        break;
      case Date:
      case DateTime:
        return DateTimeTransProcesser.getInstacne();
      case Binary:
        return BinaryTransProcesser.getInstacne();
    }

    String errorMsg = "#GSPBefError#字段["+propertyName+"]没有找到字段类型为"
            + fieldType
            + "，数据库类型为"
            + (dbDataType == null ? "null" : dbDataType.toString())
            + "的转换器"
            + "#GSPBefError#";
    throw new CefRepositoryException(errorMsg);
  }

  private static Class getEnumPropertyInfoClass(DataTypePropertyInfo dataTypePropertyInfo)
  {
    if(dataTypePropertyInfo.getObjectInfo()==null)
      throw new CefRepositoryException();
    if(dataTypePropertyInfo.getObjectInfo() instanceof  EnumPropertyInfo)
    {
      return ((EnumPropertyInfo)dataTypePropertyInfo.getObjectInfo()).getEnumType();
    }
    if(dataTypePropertyInfo .getObjectInfo() instanceof  SimpleEnumUdtPropertyInfo)
    {
      return ((SimpleEnumUdtPropertyInfo)dataTypePropertyInfo.getObjectInfo()).getEnumInfo().getEnumType();
    }
    throw new  CefRepositoryException();
  }
}
